package com.tungse.minio.tools;

import org.apache.commons.codec.digest.DigestUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

public class FileSplitUtil {

    // 计算文件MD5
    public static String calculateFileMD5(File file) throws IOException {
        try (FileInputStream fis = new FileInputStream(file)) {
            return DigestUtils.md5Hex(fis);
        }
    }

    // 分割文件
    public static List<File> splitFile(File sourceFile, long chunkSize) throws IOException {
        List<File> chunkFiles = new ArrayList<>();

        try (RandomAccessFile raf = new RandomAccessFile(sourceFile, "r")) {
            long totalSize = raf.length();
            long chunks = (long) Math.ceil((double) totalSize / chunkSize);

            for (int i = 0; i < chunks; i++) {
                long start = i * chunkSize;
                long end = Math.min(start + chunkSize, totalSize);
                long length = end - start;

                File chunkFile = new File(sourceFile.getParent(), sourceFile.getName() + ".part" + i);
                try (RandomAccessFile outRaf = new RandomAccessFile(chunkFile, "rw")) {
                    raf.seek(start);
                    byte[] buffer = new byte[4096];
                    long remaining = length;

                    while (remaining > 0) {
                        int read = raf.read(buffer, 0, (int) Math.min(buffer.length, remaining));
                        if (read == -1) break;
                        outRaf.write(buffer, 0, read);
                        remaining -= read;
                    }
                }
                chunkFiles.add(chunkFile);
            }
        }

        return chunkFiles;
    }

    // 合并分片文件
    public static void mergeChunks(String targetFilePath, List<File> chunks) throws IOException {
        File targetFile = new File(targetFilePath);
        try (RandomAccessFile raf = new RandomAccessFile(targetFile, "rw")) {
            for (File chunk : chunks) {
                try (FileInputStream fis = new FileInputStream(chunk)) {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = fis.read(buffer)) != -1) {
                        raf.write(buffer, 0, bytesRead);
                    }
                }
            }
        }

        // 清理分片文件
        for (File chunk : chunks) {
            chunk.delete();
        }
    }
}